from django.utils import timezone
from django.db import models

from apps.base.models import BaseModel


class Table(BaseModel):
    name = models.CharField('表名', max_length=64, help_text='表的主题 例: 论文表、专著表、用户表等，必填', unique=True)
    descriptions = models.CharField('描述', max_length=255, blank=True)

    @staticmethod
    def get_table_fields(instance):
        return list(instance.table_fields_table.all().values_list('field_tag', flat=True))

    class Meta:
        db_table = 'dynamic_table'
        verbose_name = '自定义表名'
        verbose_name_plural = verbose_name
        ordering = ('-modified_at',)

    def __str__(self):
        return self.name


class TableFields(BaseModel):
    TYPE_CHOICES = [('int', '整型'), ('float', '浮点型'), ('str', '字符串'), ('date', '日期'), ('datetime', '时间'),
                    ('bool', '布尔值'), ('uuid', 'UUID'), ('email', '邮箱'), ('img', '图片'), ('file', '文件')]

    field_name = models.CharField('字段名称', max_length=64, help_text='例: 创建时间、姓名')
    field_tag = models.CharField('字段标识', max_length=64, help_text='例: create_time， 必须是符合字段命名规范的（数字字母和下划线的组合，数字不做为首字母）')
    field_type = models.CharField('字段类型', max_length=12, choices=TYPE_CHOICES)
    descriptions = models.CharField('字段描述', max_length=255, blank=True, help_text='诸如用途、注意事项等')
    table = models.ForeignKey(Table, related_name='table_fields_table', on_delete=models.CASCADE, verbose_name='关联表名称')
    order = models.IntegerField('字段显示顺序', default=0)
    is_blank = models.BooleanField('是否必填', default=True)
    is_search = models.BooleanField('是否作为搜索字段', default=False)
    extra_conditions = models.TextField(verbose_name='其他条件', blank=True,
                                        help_text='json类型，其他额外的条件,例如当类型为字符串时，可以添加额外条件' +
                                                  ' {"max_length": 128, "min_length": 64}；当类型为整型时，可以添加额外条件' +
                                                  '{"min_value": 0, "max_value": 64},即最小值为0，最大值为64' +
                                                  '{"default_value": 0} 默认值')

    class Meta:
        db_table = 'dynamic_table_fields'
        verbose_name = '记录表结构具体字段'
        verbose_name_plural = verbose_name
        ordering = ('order', '-modified_at')

    def __str__(self):
        return self.field_name + '---' + self.field_tag + '---' + self.field_type


class DataRecord(BaseModel):
    created_at = models.DateTimeField(verbose_name='创建时间', default=timezone.now)
    table = models.ForeignKey(Table, verbose_name='关联表结构', on_delete=models.CASCADE, related_name='data_record_table')
    row_num = models.IntegerField(verbose_name='行数', default=0)
    field_tag = models.CharField('字段标识', max_length=64, default='')
    field_value = models.TextField('存的值', default='')

    @classmethod
    def get_instance_dict(cls, row: int, table_instance):
        table_fields = Table.get_table_fields(table_instance)
        all_records = cls.objects.filter(row_num=row).values('field_tag', 'field_value')
        if all_records.exists():
            has_value_records = {x['field_tag']: x['field_value']for x in all_records if x['field_tag'] in table_fields}
            for x in table_fields:
                has_value_records['row_num'] = row
                if x not in has_value_records:
                    has_value_records[x] = None
            return has_value_records

    @classmethod
    def get_data_by_rows(cls, row_range: list, table_instance):
        result = []
        for row in row_range:
            if cls.get_instance_dict(row, table_instance):
                result.append(cls.get_instance_dict(row, table_instance))
        return result

    class Meta:
        db_table = 'dynamic_data_record'
        verbose_name = '数据存储表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.id
